import apiInfo from './apiInfo';
import dataInfo from './dataInfo';
import http from '@ohos.net.http';
import utils from '../../core/utils';
import logger from '../../core/logger';
import apiProvider from './apiProvider';
import current from '../../core/current';
import { API_USER_AGENT, HOST } from '../../core/dict';
import apiKeyInfo from '../../model/common/apiKeyInfo';

export default class apiClient {
  private readonly getHeader: object = {
    "referer": HOST,
    "app-key": "android64",
    "user-agent": API_USER_AGENT,
    "x-bili-aurora-zone": "sh001",
    "x-bili-aurora-eid": "UlMFQVcABlAH"
  }
  private readonly postHeader: object = {
    "app-key": "android64",
    "referer": HOST,
    "user-agent": API_USER_AGENT,
    "x-bili-aurora-zone": "sh001",
    "x-bili-aurora-eid": "UlMFQVcABlAH",
    "content-type": "application/x-www-form-urlencoded"
  }

  constructor() {
    this.loadCookie();
  }

  private loadCookie() {
    try {
      let cookie = `buvid3=${utils.buvid()}`;
      cookie = current.instance.cookies;
      if (utils.isEmpty(cookie))
        cookie = `buvid3=${utils.buvid()}`;
      let cookies = {
        "cookie": cookie
      };
      Object.assign(this.getHeader, cookies);
      Object.assign(this.postHeader, cookies);
    } catch (e) {
      logger.error(e);
    }
  }

  public getResult(info: apiInfo | string, keyInfo: apiKeyInfo = apiProvider.AndroidKey, params: boolean = true): Promise<any> {
    return new Promise((resolve) => {
      if (typeof info == 'string') {
        this.loadCookie();
        let httpRequest = http.createHttp();
        httpRequest.request(info, {
          method: http.RequestMethod.GET,
          header: this.getHeader,
          connectTimeout: 5000,
          readTimeout: 5000
        }, (err, data) => {
          try {
            if (!err && data.responseCode == http.ResponseCode.OK) {
              if (typeof data.result == 'string') {
                let json = JSON.parse(data.result.toString());
                resolve(json);
              } else {
                let json = String.fromCharCode.apply(null, new Uint16Array(data.result as ArrayBuffer));
                resolve(json);
              }
            } else {
              logger.info('gethttp error:' + JSON.stringify(err));
              resolve(err.message);
            }
          } catch (e) {
            logger.error(e);
            resolve(e);
          }
          httpRequest.destroy();
        });
      } else
        info.toString(params, keyInfo).then((url => {
          this.getResult(url).then((res) => resolve(res));
        }));
    });
  }

  public getResultXml(info: string): Promise<string> {
    return new Promise((resolve) => {
      this.loadCookie();
      let httpRequest = http.createHttp();
      httpRequest.request(info, {
        method: http.RequestMethod.GET,
        header: this.getHeader,
        connectTimeout: 5000,
        readTimeout: 5000
      }, (err, data) => {
        try {
          if (!err && data.responseCode == http.ResponseCode.OK) {
            if (typeof data.result == 'string') {
              resolve(data.result.toString());
            } else {
              let json = String.fromCharCode.apply(null, new Uint16Array(data.result as ArrayBuffer));
              resolve(json);
            }
          } else {
            logger.info('gethttp error:' + JSON.stringify(err));
            resolve(err.message);
          }
        } catch (e) {
          logger.error(e);
          resolve(e);
        }
        httpRequest.destroy();
      });
    });
  }

  public postResult(url: string, postContent: dataInfo | string, keyInfo: apiKeyInfo = apiProvider.AndroidKey): Promise<any> {
    return new Promise((resolve) => {
      if (typeof postContent == 'string') {
        this.loadCookie();
        let httpRequest = http.createHttp();
        httpRequest.request(url, {
          method: http.RequestMethod.POST,
          header: this.postHeader,
          extraData: postContent,
          connectTimeout: 5000,
          readTimeout: 5000
        }, (err, data) => {
          try {
            if (!err && data.responseCode == http.ResponseCode.OK) {
              if (typeof data.result == 'string') {
                let json = JSON.parse(data.result.toString());
                resolve(json);
              } else {
                let json = String.fromCharCode.apply(null, new Uint16Array(data.result as ArrayBuffer));
                resolve(json);
              }
            } else {
              logger.error('gethttp error:' + JSON.stringify(err));
              resolve(err.message);
            }
          } catch (e) {
            resolve('');
            logger.error(e);
          }
          httpRequest.destroy();
        });
      } else {
        let info = postContent.toString(keyInfo);
        this.postResult(url, info).then((res) => resolve(res));
      }
    });
  }
}